/*
 * Copyright (C) 2009 AnK Team
 *	 Andrey Korolev
 *	 Anna Krel
 *	 Anna Kapanina
 *	 
 *	 http://code.google.com/p/ankfood/	
 *    
     
 *    Licensed under the GNU General Public License, Version 2.0 (the "License");
 *
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *         http://www.gnu.org/licenses/gpl-2.0.html

 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,

 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */



package org.ank.food;

import java.security.InvalidParameterException;

import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.util.Log;
import android.widget.SimpleCursorAdapter;

public class ProfileManager {
	
	public static final String PREFS_NAME = "profman";
	public static final String PREFS_MODE = "profman mode";
	public static final String PREFS_CUR_PROF = "profman cur prof";
	
	public static final double LB_TO_KG = 0.45359237;
	public static final double IN_TO_CM = 2.54;
	
	public static final int SEDENTARY = 0;
	public static final int LOW_ACTIVE = 1;
	public static final int ACTIVE = 2;
	public static final int VERY_ACTIVE = 3;
	
	public static final int PROFILE_MODE_CREATE = 0;
    public static final int PROFILE_MODE_EDIT = 1;
    
    public static final int FEMALE = 0;
    public static final int MALE = 1;
    
    //data for calculating energy qoutas
    
    
    
    public String currentProfileName;
    
    private int gender, age, weight, height;
    private double physActivity;
    private ContentValues values;
    private Context context;
	
	
    private volatile static ProfileManager instance;
	private int mode;
	
	private SimpleCursorAdapter adapter;
	

	
	private ProfileManager(Context c) {
		this.values = new ContentValues();
		this.context = c;
		
	}
 
    public static ProfileManager getInstance(Context c) {
        if (instance == null) {
            synchronized (ProfileManager.class) {
                if (instance == null) {
                    instance = new ProfileManager(c);
                    
                }
            }
        }
        return instance;
    }
    
    public void deleteProfile(int id){
    	if(getCurrentProfileId() == id){
    		setCurrentProfile(null);
    	}
    	context.getContentResolver().delete(ProfileProvider.CONTENT_URI, 
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.ID]+" = "+String.valueOf(id), null);
    	//delete all advices and eaten connected to this profile
    	AdviceManager.getInstance(context).deleteProfile(id);
    }
    
    public int getCurrentProfileGender(){
    	currentProfileName = context.getSharedPreferences(PREFS_NAME, 0).getString(PREFS_CUR_PROF, null);
    	Cursor c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.GENDER]}, 
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]+" = \""+currentProfileName+"\"", 
    			new String[]{}, null);
    	c.moveToFirst();
    	int result = c.getInt(0);
    	c.close();
    	return result;
    }
    
    public int getCurrentProfileAge(){
    	currentProfileName = context.getSharedPreferences(PREFS_NAME, 0).getString(PREFS_CUR_PROF, null);
    	Cursor c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.AGE]}, 
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]+" = \""+currentProfileName+"\"", 
    			new String[]{}, null);
    	c.moveToFirst();
    	int result = c.getInt(0);
    	c.close();
    	return result;
    }
    
    public int getCurrentProfileWeight(){
    	currentProfileName = context.getSharedPreferences(PREFS_NAME, 0).getString(PREFS_CUR_PROF, null);
    	Cursor c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.WEIGHT]}, 
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]+" = \""+currentProfileName+"\"", 
    			new String[]{}, null);
    	c.moveToFirst();
    	int result = c.getInt(0);
    	c.close();
    	return result;
    }
    
    public int getCurrentProfileHeight(){
    	currentProfileName = context.getSharedPreferences(PREFS_NAME, 0).getString(PREFS_CUR_PROF, null);
    	Cursor c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.HEIGHT]}, 
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]+" = \""+currentProfileName+"\"", 
    			new String[]{}, null);
    	c.moveToFirst();
    	int result = c.getInt(0);
    	c.close();
    	return result;
    }
    
    public int getCurrentProfilePhysAct(){
    	currentProfileName = context.getSharedPreferences(PREFS_NAME, 0).getString(PREFS_CUR_PROF, null);
    	Cursor c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.PHYS_ACT]}, 
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]+" = \""+currentProfileName+"\"", 
    			null, null);
    	c.moveToFirst();
    	int result = c.getInt(0);
    	c.close();
    	return result;
    }
    
    public void setNewProfileName(CharSequence s){
//    	//Log.v("profile","New name is "+s);
    	values.put(ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME], s.toString());
    }
    
    public String getNewProfileName(){
    	if ( values.containsKey(ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]) )
    			return values.getAsString(ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]);
    	return null;
    }
    
    public void setNewProfileGender(int g){
    	gender = g;
//    	//Log.v("profile","New gender is "+g);
    	values.put(ProfileProvider.COLUMN_NAMES[ProfileProvider.GENDER], g);
    }
    
    public int getNewProfileGender(){
    	if ( values.containsKey(ProfileProvider.COLUMN_NAMES[ProfileProvider.GENDER]) )
    		return values.getAsInteger(ProfileProvider.COLUMN_NAMES[ProfileProvider.GENDER]).intValue();
    	return 0;
    }
    
    public void setNewProfileAge(int a){
    	age = a;
//    	//Log.v("profile","New age is "+a);
    	values.put(ProfileProvider.COLUMN_NAMES[ProfileProvider.AGE], a);
    }
    
    public int getNewProfileAge(){
    	if ( values.containsKey(ProfileProvider.COLUMN_NAMES[ProfileProvider.AGE]) )
    		return values.getAsInteger(ProfileProvider.COLUMN_NAMES[ProfileProvider.AGE]).intValue();
    	return 0;
    }
    
    public void setNewProfileWeight(int w){
    	weight = w;
//    	//Log.v("profile","New weight is "+w);
    	values.put(ProfileProvider.COLUMN_NAMES[ProfileProvider.WEIGHT], w);
//    	//Log.v("setNewProfileWeight","new weight is "+w);
    }
    
    public int getNewProfileWeight(){
    	if ( values.containsKey(ProfileProvider.COLUMN_NAMES[ProfileProvider.WEIGHT]) )
    		return values.getAsInteger(ProfileProvider.COLUMN_NAMES[ProfileProvider.WEIGHT]).intValue();
    	return 0;
    }

    public void setNewProfileHeight(int h){
    	height = h;
//    	//Log.v("profile","New height is "+h);
    	values.put(ProfileProvider.COLUMN_NAMES[ProfileProvider.HEIGHT], h);
    }
    
    public int getNewProfileHeight(){
    	if ( values.containsKey(ProfileProvider.COLUMN_NAMES[ProfileProvider.HEIGHT]) )
    		return values.getAsInteger(ProfileProvider.COLUMN_NAMES[ProfileProvider.HEIGHT]).intValue();
    	return 0;
    }

    
    public void setNewProfilePhysActivity(int p){
//    	Log.v("profile","setPA, first p = "+p);
    	switch (p){
    	case SEDENTARY :
//    		Log.v("profile","sedentary = "+SEDENTARY);
//    		Log.v("profile","p = "+age);
    		physActivity = 1.0;
    		break;
    	case LOW_ACTIVE :
    		physActivity = 1.12;
    		break;
    	case ACTIVE :
    		physActivity = 1.27;
    		break;
    	case VERY_ACTIVE :
    		physActivity = 1.45;
    		break;
    	}
//    	Log.v("profile","New phys act is "+p+" or PA = "+physActivity);
    	values.put(ProfileProvider.COLUMN_NAMES[ProfileProvider.PHYS_ACT], p);
    }
    
    public int getNewProfilePhysActivity(){
    	if ( values.containsKey(ProfileProvider.COLUMN_NAMES[ProfileProvider.PHYS_ACT]) )
    		return values.getAsInteger(ProfileProvider.COLUMN_NAMES[ProfileProvider.PHYS_ACT]).intValue();
    	return 0;
    }

    
//    public String getNewProfileInfo(){
//    	StringBuffer buf = new StringBuffer(context.getString(R.string.save_profile_profile_info_title));
//    	buf.append('\n').
//    	append(context.getString(R.string.save_profile_profile_name)).
//    	append(" : ").append(   values.getAsString( ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME] )   ).
//    	append('\n').
//    	append(context.getString(R.string.save_profile_profile_gender)).
//    	append(" : ");
//    	if (  values.getAsInteger( ProfileProvider.COLUMN_NAMES[ProfileProvider.GENDER] ).intValue() == 
//    		ProfileManager.FEMALE)
//    		buf.append(   context.getString(R.string.gender_female)   );
//    	else
//    		buf.append(   context.getString(R.string.gender_male)   );
//    	buf.append('\n').
//    	append(context.getString(R.string.save_profile_profile_age)).
//    	append(" : ").append(   values.getAsInteger( ProfileProvider.COLUMN_NAMES[ProfileProvider.AGE] )   ).
//    	append('\n').
//    	append(context.getString(R.string.save_profile_profile_weight)).
//    	append(" : ").append(   values.getAsInteger( ProfileProvider.COLUMN_NAMES[ProfileProvider.WEIGHT] )   ).
//    	append('\n').
//    	append(context.getString(R.string.save_profile_profile_height)).
//    	append(" : ").append(   values.getAsInteger( ProfileProvider.COLUMN_NAMES[ProfileProvider.HEIGHT] )   );
//    	
//    	return buf.toString();
//    }
    
    public void saveNewOrUpdateProfile(){
    	//determine and put an id for the new profile
//    	//Log.v("profile","save new profile");
    	
    	
    	//determine and put nutritients qoutas for the new profile based on parametrs provided
    		//first calculate the amount of energy needed daily
    	int totalEnergy = 0;
//    	Log.v("profile","before counting energy: name = "+getNewProfileName());
//    	Log.v("profile","before counting energy: age = "+age);
//    	Log.v("profile","before counting energy: physAct = "+physActivity);
//    	Log.v("profile","before counting energy: weight = "+weight);
//    	Log.v("profile","before counting energy: height = "+height);
    	switch(gender){
    	case FEMALE :
    		totalEnergy = (int)Math.round( 354 - 6.91 * age + physActivity * (9.36 * weight + 726 * height / 100) );
    		break;
    	case MALE :
    		totalEnergy = (int)Math.round( 662 - 9.53 * age + physActivity * (15.91 * weight + 539.6 * height / 100) );
    		break;
    	}
//    	Log.v("profile","so total energy = "+totalEnergy);
    	//Log.v("save profile", "total energy = "+totalEnergy);
    		//then find the qoutas based on age
    	double protPercent, fatPercent/*, carboPercent*/;
    	int protEnergy, fatEnergy, carboEnergy;
    	if (age <= 3){
    		protPercent = 0.15;
    		fatPercent = 0.35;
//    		carboPercent = 0.5;
    	}else if(age > 18){
    		protPercent = 0.2;
    		fatPercent = 0.3;
//    		carboPercent = 0.5;
    	}else{
    		protPercent = 0.25;
    		fatPercent = 0.5;
//    		carboPercent = 0.25;
    	}
    	protEnergy = (int)Math.round(totalEnergy * protPercent);
    	fatEnergy = (int)Math.round(totalEnergy * fatPercent);
    	carboEnergy = totalEnergy - protEnergy - fatEnergy;
    	//Log.v("save profile", "prot E = "+protEnergy);
    	//Log.v("save profile", "fatt E = "+fatEnergy);
    	//Log.v("save profile", "carbo E = "+carboEnergy);
    	values.put(ProfileProvider.COLUMN_NAMES[ProfileProvider.PROT_QUOTA], protEnergy);
    	values.put(ProfileProvider.COLUMN_NAMES[ProfileProvider.FAT_QUOTA], fatEnergy);
    	values.put(ProfileProvider.COLUMN_NAMES[ProfileProvider.CARBO_QUOTA], carboEnergy);
    	
    	if ( ( mode = getProfileMode() ) == PROFILE_MODE_EDIT){
    		values.put(ProfileProvider.COLUMN_NAMES[ProfileProvider.ID],getCurrentProfileId());
    		context.getContentResolver().update(ProfileProvider.CONTENT_URI, values, 
    				ProfileProvider.COLUMN_NAMES[ProfileProvider.ID]+" = "+
    				String.valueOf(getCurrentProfileId()), null);
    		return;
    	}
    	values.put(ProfileProvider.COLUMN_NAMES[ProfileProvider.ID], 
    			findMaxIndex()+1 );
    	
    	context.getContentResolver().insert(ProfileProvider.CONTENT_URI, values);
    	setCurrentProfile(values.getAsString(ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]));
    	values = new ContentValues();
    }
    
    public void setCurrentProfile(String name){
    	currentProfileName = name;
    	SharedPreferences.Editor editor = context.getSharedPreferences(PREFS_NAME, 0).edit();
    	editor.putString(PREFS_CUR_PROF, name);
    	editor.commit();
//    	Log.v("profile manager","new current profile is "+name);
    }
    
    public void setCurrentProfile(int id){
    	Cursor c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]}, 
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.ID]+" = "+String.valueOf(id),
    			null,null);
//    	//Log.v("profile manager","set cur profile: cursor")
    	c.moveToFirst();
    	currentProfileName = c.getString(0);
    	SharedPreferences.Editor editor = context.getSharedPreferences(PREFS_NAME, 0).edit();
    	editor.putString(PREFS_CUR_PROF, currentProfileName);
    	editor.commit();
    	c.close();
//    	//Log.v("profile manager","new current profile is "+currentProfileName);
    }
    
    public String getCurrentProfileName(){
//    	//Log.v("profile manager","current profile is "+currentProfileName);
    	SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
    	return prefs.getString(PREFS_CUR_PROF, null);
    }
    public int getCurrentProfileId(){
//    	int id = 0;
    	currentProfileName = context.getSharedPreferences(PREFS_NAME, 0).getString(PREFS_CUR_PROF, null);
    	if (currentProfileName == null || currentProfileName.equals(""))
    		return -1;
    	Cursor c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.ID]}, 
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]+" = \""+currentProfileName+"\"", 
    			new String[]{}, null);
    	c.moveToFirst();
    	if (c.getCount() == 0){
    		c.close();
    		return -1;
    	}
    	int result = c.getInt(0);
    	c.close();
    	return result;
    }
    public int getProtQuota(){
    	currentProfileName = context.getSharedPreferences(PREFS_NAME, 0).getString(PREFS_CUR_PROF, null);
    	Cursor c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.PROT_QUOTA]}, 
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]+" = \""+currentProfileName+"\"", 
    			new String[]{}, null);
    	c.moveToFirst();
    	int result = c.getInt(0);
    	c.close();
    	return result;
    }
    public int getFatQuota(){
    	currentProfileName = context.getSharedPreferences(PREFS_NAME, 0).getString(PREFS_CUR_PROF, null);
    	Cursor c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.FAT_QUOTA]}, 
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]+" = \""+currentProfileName+"\"", 
    			new String[]{}, null);
    	c.moveToFirst();
    	int result = c.getInt(0);
    	c.close();
    	return result;
    }
    public int getCarboQuota(){
    	currentProfileName = context.getSharedPreferences(PREFS_NAME, 0).getString(PREFS_CUR_PROF, null);
    	Cursor c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.CARBO_QUOTA]}, 
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]+" = \""+currentProfileName+"\"", 
    			new String[]{}, null);
    	c.moveToFirst();
    	int result = c.getInt(0);
    	c.close();
    	return result;
    }
    
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //the cursor here is not closed!!!    
    public SimpleCursorAdapter getProfilesAdapter(){
    	Cursor cursor = context.getContentResolver().query(ProfileProvider.CONTENT_URI,
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME],
    						 ProfileProvider.COLUMN_NAMES[ProfileProvider.ID]}, 
    			null, null/*new String[]{}*/, ProfileProvider.DEFAULT_SORT_ORDER);    	
    	
    	String[] returnFields = {ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]};
    	
    	adapter = new SimpleCursorAdapter(context, /*R.layout.profile_list_item*/android.R.layout.simple_list_item_1, 
    			cursor,
    			returnFields, new int[] {/*R.id.profile_list_item_text*/android.R.id.text1});
    	
    	return adapter;
    }
    
    public Cursor getProfilesCursor(){
    	return context.getContentResolver().query(ProfileProvider.CONTENT_URI,
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME],
				 ProfileProvider.COLUMN_NAMES[ProfileProvider.ID]}, 
				 null, null, ProfileProvider.DEFAULT_SORT_ORDER);
    	
    }
    
    //this metod returns the max index
    private int findMaxIndex(){
    	Cursor c;
    	c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ "max(" +ProfileProvider.COLUMN_NAMES[ProfileProvider.ID]+ ") max_id" },
    			"", new String[]{}, "");
    	if (c.getCount() == 0)
    		return 0;
    	c.moveToFirst();
    	int result = c.getInt(0);
    	c.close();
    	return result;
    }
    
    
    public void setProfileMode(int newMode){
    	SharedPreferences.Editor editor = context.getSharedPreferences(PREFS_NAME, 0).edit();
    	switch(newMode){					 
    	case PROFILE_MODE_CREATE :
    		mode = PROFILE_MODE_CREATE;
        	editor.putInt(PREFS_MODE, mode);
        	editor.commit();
    		break;
    	case PROFILE_MODE_EDIT :
    		this.mode = PROFILE_MODE_EDIT;
        	editor.putInt(PREFS_MODE, mode);
        	editor.commit();
    		break;
    	default :
    		throw new InvalidParameterException("Can't set mode to " + mode);
    		
    	}
    	
    }
    public int getProfileMode(){
    	return context.getSharedPreferences(PREFS_NAME, 0).getInt(PREFS_MODE, PROFILE_MODE_CREATE);
    }
    
    public String getProfileNameById(int id){
    	Cursor c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]},
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.ID]+" = "+String.valueOf(id),
    			null, null);
    	c.moveToFirst();
    	
//    	Log.v("name by id","count = "+c.getCount());
//    	Log.v("name by id","col name(0) = "+c.getColumnName(0));
//    	c.moveToFirst();
    	
    	String result = c.getString(0);
    	c.close();
    	return result;
    }
    
    public boolean profileNameExists(String name){
    	Cursor c = context.getContentResolver().query(ProfileProvider.CONTENT_URI, 
    			new String[]{ProfileProvider.COLUMN_NAMES[ProfileProvider.ID]},
    			ProfileProvider.COLUMN_NAMES[ProfileProvider.NAME]+" = \""+name+"\"",
    			null, null);
    	int a = c.getCount();
    	c.close();
    	return (a > 0)? true : false;
    }
    
//    public void saveState(){
//    	SharedPreferences.Editor editor = context.getSharedPreferences(, PROFILE_MODE_CREATE) 
//    }

}
